package org.boyan.modules.controller;

import com.alibaba.fastjson.JSON;
import org.boyan.cases.ExcelToCaseBody;
import org.boyan.cases.ExcelToDemandInfo;
import org.boyan.cases.ExcelToNonFunctionalDemand;
import org.boyan.common.api.vo.Result;
import org.boyan.common.util.DateUtils;
import org.boyan.common.util.UUIDGenerator;
import org.boyan.entity.cases.Case;
import org.boyan.entity.cases.DemandInfo;
import org.boyan.entity.cases.NonFunctionalDemand;
import org.boyan.entity.trans.Trans;
import org.boyan.esb.GenerateEsbExcel;
import org.boyan.modules.service.CaseService;
import org.boyan.modules.service.CaseTransRelationService;
import org.boyan.modules.service.TransService;
import org.boyan.modules.vo.CaseVo;
import org.boyan.utils.ExcelExportUtils;
import org.boyan.utils.IdGenerate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

@RestController
@RequestMapping("/case")
public class CaseController {
    @Value("${boyan.path.upload}")
    private String uploadPath;

    @Autowired
    private CaseService caseService;

    @Autowired
    private TransService transService;

    @Autowired
    private CaseTransRelationService caseTransRelationService;

    @PostMapping("/upload")
    public Result uploadCase(MultipartFile file){
        Map<String,Object> retMap=new HashMap<>();
        DemandInfo demandInfo= ExcelToDemandInfo.getDemandInfo(file);
        NonFunctionalDemand nonFunctionalDemand= ExcelToNonFunctionalDemand.getNonFunctionalDemand(file);
        List<Map<String,Object>> caseBodyList= ExcelToCaseBody.getCaseBody(file);
        retMap.put("demand",demandInfo);
        retMap.put("nonfunc",nonFunctionalDemand);
        retMap.put("body",caseBodyList);
        return Result.OK(retMap);
    }

    @PostMapping("/import")
    public Result importCase(@RequestBody Map<String,Object> map){
        List<Map<String,Object>> bodyList= (List<Map<String, Object>>) map.get("body");
        //只修改传入参数中交易的id和状态返回，用于与caseCreateModal绑定
        for(Map<String,Object> m:bodyList){
            Trans trans= JSON.parseObject(JSON.toJSONString(m.get("trans")),Trans.class);
            trans.setId(UUIDGenerator.generate());
            trans.setTransStatus(1);
            m.replace("trans",trans);
        }
        return Result.OK(map);
    }

    @PostMapping("/add")
    @Transactional
    public Result addCase(@RequestBody Map<String,Object>map){
        //对case数据进行处理
        Map<String,Object> caseMap= (Map<String, Object>) map.get("caseInfo");
        String createBy= (String) map.get("createBy");
        Case newCase=JSON.parseObject(JSON.toJSONString(caseMap),Case.class);
        newCase.setId(UUIDGenerator.generate());
        newCase.setCreateBy(createBy);
        newCase.setCreateTime(DateUtils.formatDate(new Date(),"yyyy-MM-dd"));
        newCase.setCaseNo(IdGenerate.getId());
        newCase.setCaseStatus(2);
        //对caseBody数据进行处理，取出交易相关，进行创建交易
        Map<String,Object> bodyMap= (Map<String, Object>) map.get("caseBody");
        //将bodyMap的信息保存，此处保存excel文件到服务器
        String sourcePath=uploadPath+"/modules/SPDB-HDS-需求调研评估表(新增交易需求).xlsx";
        String targetPath=uploadPath+"/excel/"+newCase.getCaseNo()+".xlsx";
        try{
            ExcelExportUtils.copyModuleFile(sourcePath,targetPath);
            ExcelExportUtils.exportCase(targetPath,bodyMap,false);
        }catch (Exception e){
            e.printStackTrace();
            //删除创建出来的文件，防止占空间
            File targetFile=new File(targetPath);
            if(targetFile.exists()){
                targetFile.delete();
            }
            return Result.error("此处发生excel相关问题,创建文件失败");
        }
        //获取trans
        List<Map<String,Object>> bodyList= (List<Map<String, Object>>) bodyMap.get("body");
        List<Trans> transList=new ArrayList<>();
        for(Map<String,Object>m:bodyList){
            Trans trans=JSON.parseObject(JSON.toJSONString(m.get("trans")),Trans.class);
            transList.add(trans);
        }
        //新增case和trans
        boolean caseFlag=caseService.addCase(newCase);
        if(caseFlag){
            if(transService.addTransList(transList)) {
                //添加为case和trans添加relation
                if(caseTransRelationService.addRelation(newCase.getId(),transList)){
                    return Result.OK("创建成功");
                }
            }
        }
        return Result.error("创建失败");
    }

    //当前page，pagesize和查询条件获取数据库中case信息
    @PostMapping("/getCaseList")
    public Result getCaseList(@RequestBody Map<String,Object>map){
        int current= (int) map.get("current");
        int size= (int) map.get("size");
        Map<String,Object> caseMap= (Map<String, Object>) map.get("criteria");
        Case caseCriteria=new Case();
        if(caseMap!=null){
            caseCriteria=JSON.parseObject(JSON.toJSONString(caseMap),Case.class);
        }
        List<CaseVo> caseVoList=caseService.getCaseVoList(current,size,caseCriteria);
        int total=caseService.getTotalByCriteria(caseCriteria);
        Map<String,Object> retMap=new HashMap<>();
        retMap.put("total",total);
        retMap.put("data",caseVoList);
        return Result.OK(retMap);
    }

    //点击caseId展示case信息
    @GetMapping("/showCaseInfo/{id}")
    public Result showCaseInfo(@PathVariable String id){
        //根据caseId查出case信息
        Case caseInfo=caseService.getCaseInfoById(id);
        //根据caseNo找到服务器中的excel文件
        String filePath=uploadPath+"/excel/"+caseInfo.getCaseNo()+".xlsx";
        File file =new File (filePath);
        if(!file.exists()){
            return Result.error("文件丢失,请重新上传");
        }
        Map<String,Object> retMap=new HashMap<>();
        DemandInfo demandInfo= ExcelToDemandInfo.getDemandInfo(file);
        NonFunctionalDemand nonFunctionalDemand= ExcelToNonFunctionalDemand.getNonFunctionalDemand(file);
        //根据caseId找出List<Trans>
        List<Trans> transList=transService.getTransListByCaseId(caseInfo.getId());
        List<Map<String,Object>> caseBodyList= ExcelToCaseBody.getCaseBody(file);
        //为caseBody中的交易添加交易list的id等
        for(int i=0;i<caseBodyList.size();i++){
            Trans t= (Trans) caseBodyList.get(i).get("trans");
            for(Trans trans:transList){
                if(trans.getTransOrder()==i){
                    t.setId(trans.getId());
                }
            }
        }
        retMap.put("demand",demandInfo);
        retMap.put("nonfunc",nonFunctionalDemand);
        retMap.put("body",caseBodyList);
        retMap.put("caseInfo",caseInfo);
        return Result.OK(retMap);
    }

    //修改case的方法
    @PostMapping("/edit")
    @Transactional
    public Result editCase(@RequestBody Map<String ,Object>map){
        //解开map中的数据
        List<Map<String,Object>> bodyList= (List<Map<String, Object>>) map.get("body");
        Map<String,Object> caseMap= (Map<String, Object>) map.get("caseInfo");
        Case caseInfo=JSON.parseObject(JSON.toJSONString(caseMap),Case.class);
        //caseInfo转换一下日期格式
        caseInfo.setOperationDate(caseInfo.getOperationDate().substring(0,10));
        //修改caseInfo
        boolean flag=caseService.editCase(caseInfo);
        if(flag){
            List<Trans> transList=new ArrayList<>();
            for(int i=0;i<bodyList.size();i++){
                Map<String,Object> transMap= (Map<String, Object>) bodyList.get(i).get("trans");
                Trans trans= JSON.parseObject(JSON.toJSONString(transMap),Trans.class);
                transList.add(trans);
            }
            if(transService.editTransList(transList)){
                //此处修改成功，对应进行服务器内excel文件的修改
                String targetPath=uploadPath+"/excel/"+caseInfo.getCaseNo()+".xlsx";
                try {
                    ExcelExportUtils.exportCase(targetPath,map,true);
                    return Result.OK("修改成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    return Result.OK("excel文件出现未知错误？？？");
                }
            }
        }
        return Result.error("修改失败");
    }

    //下载case的方法
    @GetMapping("/download/{file}")
    public void download(@PathVariable("file")String filename, HttpServletResponse response){
        String filePath=uploadPath+"/excel/"+filename+".xlsx";
        File file=new File(filePath);
        try {
            FileInputStream in=new FileInputStream(file);
            OutputStream output=response.getOutputStream();
            int len=0;
            byte[] b=new byte[1024];
            //将Content-Disposition暴露出来
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
            while((len=in.read(b))!=-1){
                output.write(b,0,len);
            }
            output.flush();
            output.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //审核case的方法
    @GetMapping("/audit/{id}")
    public Result auditCase(@PathVariable("id")String id){
        if(caseService.auditCase(id)){
            return Result.OK("审核成功");
        }
        return Result.error("审核失败");
    }

    //退回case的方法
    @GetMapping("/return/{id}")
    public Result returnCase(@PathVariable("id")String id){
        if(caseService.returnCase(id)){
            return Result.OK("退回成功");
        }
        return Result.error("退回失败");
    }

    //删除case的方法
    @GetMapping("/delete/{id}")
    @Transactional
    public Result deleteCase(@PathVariable("id")String id){
        //先根据caseId找到TransList,先删除case后则查不到caseId
        List<Trans> transList=transService.getTransListByCaseId(id);
        Case caseEntity=caseService.getCaseInfoById(id);
        //先根据caseId删除关系表
        if(caseTransRelationService.deleteRelationsByCaseId(id)){
            //删除根据Id删除Case
            if(caseService.deleteCase(id)){
                //根据caseId删除交易
                if(transService.deleteTrans(transList)){
                    //此处删除成功后，删除服务器内的Excel文件
                    String filePath=uploadPath+"/excel/"+caseEntity.getCaseNo()+".xlsx";
                    File file=new File(filePath);
                    if(file.exists()){
                        file.delete();
                    }
                    return Result.OK("退回成功");
                }
            }
        }
        return Result.error("退回失败");
    }

    //分配Case
    @PostMapping("allocateCase")
    public Result allocateCase(@RequestBody Map<String,String> map){
        String developPrincipal=map.get("develop");
        String caseId=map.get("caseId");
        boolean flag=caseService.allocateCaseByCaseId(developPrincipal,caseId);
        if(flag){
            return Result.OK("Case分配成功");
        }else {
            return Result.error("Case分配失败");
        }
    }
}
